package main

import (
	"flag"
	"fmt"
	"log/slog"
	"os"
	"sort"
	"st_data/internal/analyzer"
	"st_data/internal/database"
)

func main() {
	// 设置命令行参数
	dbConnStr := flag.String("db", "", "数据库连接字符串，例如：user:password@tcp(localhost:3306)/dbname")
	flag.Parse()

	if *dbConnStr == "" {
		slog.Error("请提供数据库连接字符串")
		flag.Usage()
		os.Exit(1)
	}

	// 设置日志
	logOpts := &slog.HandlerOptions{
		Level: slog.LevelInfo,
	}
	logger := slog.New(slog.NewTextHandler(os.Stdout, logOpts))
	slog.SetDefault(logger)

	// 连接数据库
	db, err := database.Connect(*dbConnStr)
	if err != nil {
		slog.Error("连接数据库失败", "error", err)
		os.Exit(1)
	}
	defer db.Close()

	// 分析表结构
	tableAnalyzer := analyzer.New(db)

	// 查找重复表
	duplicates, err := tableAnalyzer.FindDuplicateTables()
	if err != nil {
		slog.Error("查找重复表失败", "error", err)
		os.Exit(1)
	}

	// 打印重复表
	if len(duplicates) > 0 {
		slog.Info("发现结构相同的表:")

		// 创建文件保存重复表信息
		duplicateFile, err := os.Create("duplicate_tables.txt")
		if err != nil {
			slog.Error("创建重复表信息文件失败", "error", err)
		} else {
			defer duplicateFile.Close()

			fmt.Fprintln(duplicateFile, "数据库重复表结构报告")
			fmt.Fprintln(duplicateFile, "====================")

			for i, group := range duplicates {
				groupInfo := fmt.Sprintf("重复组 %d: %v", i+1, group)
				slog.Info("重复组", "group", i+1, "tables", group)
				fmt.Fprintln(duplicateFile, groupInfo)
			}

			slog.Info("重复表信息已保存到", "file", "duplicate_tables.txt")
		}
	} else {
		slog.Info("未发现结构相同的表")
	}

	// 统计表记录数
	uniqueTables, err := tableAnalyzer.GetUniqueTablesWithoutDuplicates(duplicates)
	if err != nil {
		slog.Error("获取唯一表失败", "error", err)
		os.Exit(1)
	}

	// 统计每张表的记录数
	tableCounts, err := tableAnalyzer.CountRecords(uniqueTables)
	if err != nil {
		slog.Error("统计表记录数失败", "error", err)
		os.Exit(1)
	}

	// 打印统计结果
	var totalRecords int64
	slog.Info("表记录数统计:")

	// 统计总表数和重复表数
	allTables, err := db.GetTables()
	if err != nil {
		slog.Error("获取所有表失败", "error", err)
		os.Exit(1)
	}
	totalTableCount := len(allTables)
	totalDuplicateCount := 0
	for _, group := range duplicates {
		totalDuplicateCount += len(group)
	}

	// 创建一个切片来存储表名和记录数，用于排序
	type TableCount struct {
		Name  string
		Count int64
	}
	var tableCntSlice []TableCount

	for table, count := range tableCounts {
		slog.Info("表统计", "table", table, "records", count)
		totalRecords += count
		tableCntSlice = append(tableCntSlice, TableCount{Name: table, Count: count})
	}
	slog.Info("总表数", "total_tables", totalTableCount)
	slog.Info("重复表数", "duplicate_tables", totalDuplicateCount)
	slog.Info("总记录数", "total", totalRecords)

	// 按记录数排序
	sort.Slice(tableCntSlice, func(i, j int) bool {
		return tableCntSlice[i].Count > tableCntSlice[j].Count
	})

	// 将数据量最大的表写入文件
	if len(tableCntSlice) > 0 {
		largestFile, err := os.Create("largest_tables.txt")
		if err != nil {
			slog.Error("创建最大表信息文件失败", "error", err)
		} else {
			defer largestFile.Close()

			fmt.Fprintln(largestFile, "数据量最大的表")
			fmt.Fprintln(largestFile, "==============")

			// 输出最大的五张表
			count := 5
			if len(tableCntSlice) < count {
				count = len(tableCntSlice)
			}

			for i := 0; i < count; i++ {
				table := tableCntSlice[i]
				fmt.Fprintf(largestFile, "%d. %s: %d 条记录\n", i+1, table.Name, table.Count)
			}

			slog.Info("最大表信息已保存到", "file", "largest_tables.txt")
		}
	}
}
